#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include "flightMS.h"
 
 
//创建双向循环链表的头
dclist_t* create_dclist(){
 
    dclist_t* dchead = (dclist_t*)malloc(sizeof(dclist_t));
    if(dchead == NULL){
        perror("malloc failed\n");
        return NULL;
    }
 
    dchead->flight = NULL;
    dchead->before = dchead;
    dchead->next = dchead;
 
    return dchead;
}
 
//添加航班(尾插)
int insert_flight(dclist_t* dchead, flight_t* flight){
 
    if(dchead == NULL || flight == NULL){
        perror("error\n");
        return -1;
    }
 
    //申请节点空间
    dclist_t* newnode = (dclist_t*)malloc(sizeof(dclist_t));
    if(newnode == NULL){
        perror("malloc failed\n");
        return -1;
    }
 
    //申请数据空间
    newnode->flight = (flight_t*)malloc(sizeof(flight_t));
    if(newnode->flight == NULL){
        perror("malloc failed\n");
        return -1;
    }
 
    //赋值
    //*newnode->flight = *flight;
    memcpy(newnode->flight, flight, sizeof(flight_t));
    newnode->before = dchead->before;
    newnode->next = dchead;
 
    dchead->before->next = newnode;
    dchead->before = newnode;
    
    return 0;
}
 
//节点数，不包括头
int length_dclist(dclist_t* dchead){
    if(dchead == NULL || dchead->next == dchead){
        perror("error\n");
        return -1;
    }
 
    dclist_t * temp = dchead->next;
    int i = 1;
    while (temp->next != dchead){
        ++i;
        temp = temp->next;
    }
 
    return i;
}
 
//打印定义的函数指针
typedef void (*showfun_t)(flight_t* flight);
void showId(flight_t* flight){
    printf("航班号%s\n",flight->id);
}
void showRoute(flight_t* flight){
    printf("航线：%s-----%s\n",flight->begaddr,flight->endaddr);
}
void showTime(flight_t* flight){
    printf("时间段：%s-----%s\n",flight->begtime,flight->endtime);
}
void showFare(flight_t* flight){
    printf("票价：%.2f\n",flight->fare);
}
void showData(flight_t* flight){
    printf("航班日期：%s\n",flight->fldate);
}
void showType(flight_t* flight){
    printf("航班类型：%s\n",flight->fltype);
}
void showAll(flight_t* flight){
    printf("%s  %s---->%s   %s  %s     %s      %s     %.2f\n",
           flight->id, flight->begaddr, flight->endaddr,
           flight->fldate, flight->fltype, flight->begtime,
           flight->endtime,flight->fare);
    puts("");
}
 
 
 
 
 
//打印函数
void print_flight(dclist_t* dchead, showfun_t showFun){
 
    if(dchead == NULL || dchead->next == dchead){
        perror("error\n");
        return;
    }
 
    dclist_t *temp = dchead->next;
    printf("航班号  起始站  终点站  航班日期    航班类型    起飞时间   降落时间    票价\n");
    while(temp != dchead){
        showFun(temp->flight);
        temp = temp->next;
    }
 
}
 
 
//比较函数指针(第一个是链表中本身的数据，第二个是页面传过来的数据)
typedef int (*comparefun_t)(flight_t * dclistFlight, flight_t* flight);
int compareId(flight_t * dclistFlight, flight_t* flight){
    return strcmp(dclistFlight->id, flight->id);
}
int compareType(flight_t* dclistFlight, flight_t* flight){
    return strcmp(dclistFlight->fltype, flight->fltype);
}
 
 
int compareFldate(flight_t* dclistFlight, flight_t* flight){
    return strcmp(dclistFlight->fldate, flight->fldate);
}
 
//比较起始地和目的地
int compareAddress(flight_t* dclistFlight, flight_t* flight){
    int beg = strcmp(dclistFlight->begaddr, flight->begaddr);
    int end = strcmp(dclistFlight->endaddr, flight->endaddr);
 
    if(beg == 0 && end == 0){
        return 0;
    }
 
    return -1;
}
 
 
//根据航班号删除航班
int delete_dclist(dclist_t* dchead, flight_t* flight, comparefun_t comparefun){
 
    if(dchead == NULL || dchead->next == dchead || flight == NULL){
        perror("error\n");
        return -1;
    }
 
    dclist_t* temp = dchead->next;
    int res;
    while(temp != dchead){
        res = comparefun(temp->flight, flight);
        if(res == 0){
            temp->before->next = temp->next;
            temp->next->before = temp->before;
            free(temp->flight);
            free(temp);
            return 0;
        }
        temp = temp->next;
    }
 
    return -1;
}
 
//删除链表中的尾节点，读文件最后一行重复读
int delete_tdclist(dclist_t * dchead){
    
    if(dchead == NULL){
        perror("error\n");
        return -1;
    }
 
    dclist_t* temp = dchead->before;
    temp->before->next = temp->next;
    temp->next->before = temp->before;
 
    free(temp->flight);
    free(temp);
    
    return 0;
}
 
//根据航班号修改航班中时间信息
int updata_dclist(dclist_t* dchead, flight_t * flight, comparefun_t comparefun){
 
    if(dchead == NULL || dchead->next == dchead || flight == NULL){
        perror("error\n");
        return -1;
    }
 
    //先查找出对应的航班
    dclist_t* temp = dchead->next;
    while(temp != dchead){
        if(!comparefun(temp->flight,flight)){
            break;
        }
        temp = temp->next;
    }
 
    if(temp == dchead){
        perror("无此航班号\n");
        return -1;
    }
 
    //修改原航班的起飞时间，和降落时间
    strcpy(temp->flight->begtime, flight->begtime);
    strcpy(temp->flight->endtime, flight->endtime);
 
    return 0;
 
}
 
//按照类型查询航班
int find_flight_type(dclist_t* dchead, flight_t* flight, comparefun_t comparefun, showfun_t showfun){
    
    if(dchead == NULL || dchead->next == dchead || flight == NULL){
        perror("error\n");
        return -1;
    }
 
    dclist_t* temp = dchead->next;
    while(temp != dchead){
        if(!comparefun(temp->flight, flight)){
            showfun(temp->flight);
        }
        temp = temp->next;
    }
 
    return 0;
}
 
//根日期票价排序查看航班
int sort_flight_date_fare(dclist_t* dchead){
 
    if(dchead == NULL || dchead->next == dchead){
        perror("error\n");
        return -1;
    }
    int len = length_dclist(dchead);
    flight_t * arr[len];
    dclist_t* temp = dchead->next;
    int i = 0;
    //讲链表中的数据全部放入指针数组中
    while(temp != dchead){
        arr[i] = temp->flight;
        temp = temp->next;
        ++i;
    }
 
    //将数组中的航班进行排序
    flight_t* temp2 = NULL;
    for(int j = 0; j < len-1; j++){
        for(int k = 0; k < len-1-j; k++){
            if(compareFldate(arr[k], arr[k+1]) > 0){
                temp2 = arr[k];
                arr[k] = arr[k+1];
                arr[k+1] = temp2;
            }
            if(!compareFldate(arr[k], arr[k+1])){
                if(arr[k]->fare > arr[k+1]->fare){
                    temp2 = arr[k];
                    arr[k] = arr[k+1];
                    arr[k+1] = temp2;
                }
            }
        }
    }
 
    temp = NULL;
    
    //遍历输出数组中的元素
    for(int z = 0; z < len; z++){
      /*   printf("航班号:%s\t起始站:%s\t终点站:%s\t航班日期:%s\t航班类型:%s\t起飞时间:%s\t降落时间:%s\t票价:%.2f\n",
           arr[z]->id, arr[z]->begaddr, arr[z]->endaddr,
           arr[z]->fldate, arr[z]->fltype, arr[z]->begtime,
           arr[z]->endtime, arr[z]->fare);
        puts(""); */
 
        showAll(arr[z]);
    }
    return 0;
}
 
//根据起始地和目的地查询航班
int find_flight_begaddr_endaddr(dclist_t* dchead, flight_t* flight){
    
    if(dchead == NULL || flight == NULL || dchead->next == dchead){
        return -1;
    }
 
    dclist_t* temp = dchead->next;
    while(temp != dchead){
        if(!compareAddress(temp->flight, flight)){
            showAll(temp->flight);
        }
        temp = temp->next;
    }
 
    return 0;
}
 
//根据日期查询航班
int find_flight_fldate(dclist_t* dchead, flight_t* flight){
    if(dchead == NULL || flight == NULL || dchead->next == dchead){
        return -1;
    }
 
    dclist_t* temp = dchead->next;
    while(temp != dchead){
        if(!compareFldate(temp->flight, flight)){
            showAll(temp->flight);
        }
        temp = temp->next;
    }
 
    return 0;
}
 
 
#if 1
//从链表中的数据保存到文件中
void save_flight_file(dclist_t* dchead){
 
    if(dchead == NULL){
        perror("error\n");
        return;
    }
 
    FILE * fp;
    fp = fopen("/home/student/project/项目示例/flightFile.txt", "w+");
    fprintf(fp, "航班号  起始站  终点站  航班日期    航班类型    起飞时间    降落时间    票价\n");
    dclist_t* temp = dchead->next;
    while(temp != dchead){
        fprintf(fp, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%.2f\n", temp->flight->id, temp->flight->begaddr, temp->flight->endaddr,
           temp->flight->fldate, temp->flight->fltype, temp->flight->begtime,
           temp->flight->endtime, temp->flight->fare);
        temp = temp->next;
    }
 
    fclose(fp);
}
 
#endif
 
//添加一条航班就往文件中保存
void write_flight_file(dclist_t* dchead){
 
    if(dchead == NULL){
        perror("error\n");
        return;
    }
    //文件指针
    FILE* fp;
    fp = fopen("/home/student/project/项目示例/flightFile.txt","a");
    if(fp == NULL){
        perror("打开文件失败\n");
        return;
    }
 
    dclist_t* temp = dchead->before;
    fprintf(fp,"%s %s %s %s %s %s %s %.2f\n", temp->flight->id,temp->flight->begaddr, temp->flight->endaddr, temp->flight->fldate, temp->flight->fltype, temp->flight->begtime, temp->flight->endtime, temp->flight->fare);
    fclose(fp);
}
 
//从文件中读取航班
void read_flight_file(dclist_t* dchead){
    
    if(dchead == NULL){
        perror("error\n");
        return;
    }
    //文件指针
    FILE* fp;
    char buf[1024];
    char id[16], begaddr[16], endaddr[16], fldate[16], fltype[16], begtime[8], endtime[8];
 
    fp = fopen("/home/student/project/项目示例/flightFile.txt","r");
    if(fp == NULL){
        perror("打开文件失败\n");
        return;
    }
 
    //不读第一行
    fgets(buf, sizeof(buf),fp);
    flight_t flight;
    while(!feof(fp)){
 
        fscanf(fp, "%s %s %s %s %s %s %s %f", id, begaddr, endaddr, fldate, fltype, begtime, endtime, &flight.fare);
        strcpy(flight.id,id);
        strcpy(flight.begaddr,begaddr);
        strcpy(flight.endaddr,endaddr);
        strcpy(flight.fldate,fldate);
        strcpy(flight.fltype,fltype);
        strcpy(flight.begtime,begtime);
        strcpy(flight.endtime,endtime);
        insert_flight(dchead, &flight);
 
    }
 
    fclose(fp);
 
}